# -*- coding: utf-8 -*-
"""
自建支付聚合平台
"""
import json
import random
import hashlib
import logging
import requests

from common.pay.db import get_pay, update_pay_ext
from common.transaction.db import (
    add_pay_success_transaction, add_pay_fail_transaction)
from common.pay.model import PAY_STATUS
from common.pay.handler import pay_after_recharge
from common.utils import exceptions as err
from common.utils import tracker
from common.prize.db import calc_first_award

from django.conf import settings

_LOGGER = logging.getLogger('pay')

MCH_ID = settings.JUSTPAY_MCH_ID
API_KEY = settings.JUSTPAY_API_KEY
CHARGE_URL = settings.JUSTPAY_CHARGE_URL


def generate_sign(parameter, key):
    s = ''
    for k in sorted(parameter.keys()):
        s += '%s=%s&' % (k, parameter[k])
    s += 'key=%s' % key
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().upper()
    return sign


def create_charge(pay, pay_amount, sdk_version, extra_info, service, channel_id=None):
    charge_resp = {}
    total_fee = int(pay_amount)
    parameter_dict = {
        'service': service,
        'sdk_version': sdk_version,
        'mch_id': MCH_ID,
        'out_trade_no': pay.id,
        'user_id': pay.user_id,
        'body': u'商品',
        'total_fee': total_fee,
        'mch_create_ip': u'127.0.0.1',
        'notify_url': settings.JUSTPAY_NOTIFY_URL,
        'extra': json.dumps(extra_info, ensure_ascii=False),
        # 'channel_id': 290
    }
    parameter_dict['sign'] = generate_sign(parameter_dict, API_KEY)

    _LOGGER.info("justpay request data: %s", parameter_dict)
    res = requests.post(CHARGE_URL, data=parameter_dict, timeout=5).text
    _LOGGER.info("justpay data after charge: %s", res)
    res_dict = json.loads(res)
    if res_dict['status'] != 0:
        raise err.ServerError('pay service response %s %s' % (res_dict['status'], res_dict['msg']))
    return res_dict.get('data')


def check_notify_sign(request):
    data = request.POST.dict()
    sign = data['sign']
    data.pop('sign')
    calculated_sign = generate_sign(data, API_KEY)
    if sign != calculated_sign:
        _LOGGER.info("justpay sign: %s, calculated sign: %", sign, calculated_sign)
        raise err.ParamError('sign not pass, data: %s' % data)
    pay_id = data['out_trade_no']
    if not pay_id:
        _LOGGER.error("fatal error, out_trade_no not exists, data: %s" % data)
        raise err.ParamError('justpay event does not contain pay ID')

    pay = get_pay(pay_id)
    if not pay:
        raise err.DataError('pay %s not exists' % pay_id)
    if pay.status == PAY_STATUS.DONE:
        raise err.ParamError('pay %s has been notified succ' % pay_id)
    if pay.status != PAY_STATUS.SUBMIT:
        raise err.DataError('pay %s status invalid' % pay_id)
    channel_type = data['trade_type']
    trade_status = int(data['pay_result'])
    user_id = pay.user_id
    trade_no = data['trade_no']
    extra = data['extra']
    total_fee = data['total_fee']
    total_fee = float(total_fee)
    _LOGGER.info('justpay notify, pay_id:%s, extra:%s', pay_id, extra)
    extend = {
        'title': u'充值',
        'ext': {
            'trade_status': trade_status,
            'trade_no': trade_no,
            'total_fee': total_fee
        },
    }
    update_pay_ext(pay_id, extend['ext'])

    if trade_status == 2:
        _LOGGER.info('justpay check order success, user_id:%s pay_id:%s' % (user_id, pay_id))
        res = add_pay_success_transaction(user_id, pay_id, total_fee, extend)
        if res:
            tracker.track_recharge(user_id, total_fee, 'justpay')
            try:
                calc_first_award(user_id, total_fee)
                pay_after_recharge(pay, True)
            except Exception as e:
                _LOGGER.exception(
                    'pay_after_recharge of pay[%s] exception.(%s)', pay.id, e)
    else:
        add_pay_fail_transaction(user_id, pay_id, total_fee, extend)
        _LOGGER.error('justpay response data show transaction failed, data: %s', data)
